import { 
  AmbientLight,
  CubeTextureLoader,
  Mesh,
  MeshStandardMaterial,
  PerspectiveCamera,
  PointLight,
  Scene, 
  SphereGeometry, 
  TextureLoader, 
  WebGLRenderer
} from "three";
import stats from '../utils/stats';
// 调用
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GUI } from 'dat.gui';

let scene = new Scene();
let renderer = setRenderer();
let camera = setCamera();

setLight();
let sphereMesh = init();

const trackballControls = new OrbitControls(camera, renderer.domElement);
// 调整场景位置
trackballControls.target.set(0, 3, 0);

let invert = 1;
let phase = 0;
function render() {
  stats.update();
  trackballControls.update();

  // 小球动画
  if (phase > 2 * Math.PI) {
    invert = invert * -1;
    phase -= 2 * Math.PI;
  } else {
    phase += 0.02;
  }

  sphereMesh.position.z = +(21 * Math.sin(phase));
  sphereMesh.position.x = -14 + (14 * Math.cos(phase));

  if (invert < 0) {
    let pivot = 0;
    sphereMesh.position.x = (invert * (sphereMesh.position.x - pivot)) + pivot;
  }

  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render();

function setRenderer() {
  const renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 支持阴影生成 
  renderer.shadowMap.enabled = true;
  document.body.appendChild(renderer.domElement);

  return renderer
}

function setCamera(): PerspectiveCamera {
  let camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
  camera.position.set(70, 20, -50);
  scene.add( camera );

  return camera;
}

// 灯光设置
function setLight() {
  scene.add(new AmbientLight(0x888888));
}

/** 功能区 */
function init() {
  // 发光的小球
  let pointLight = new PointLight(0xffffff);
  let sphereLight = new SphereGeometry(0.2);
  let sphereMate = new MeshStandardMaterial({
    color: 0xff5808
  });
  let sphereMesh = new Mesh(sphereLight, sphereMate);
  sphereMesh.add(pointLight);
  scene.add(sphereMesh); 

  // 背景
  let urls = [
    '/textures/cubemap/car/right.png',
    '/textures/cubemap/car/left.png',
    '/textures/cubemap/car/top.png',
    '/textures/cubemap/car/bottom.png',
    '/textures/cubemap/car/front.png',
    '/textures/cubemap/car/back.png'
  ];

  let cubeLoader = new CubeTextureLoader();
  scene.background = cubeLoader.load(urls);

  let sphere1 = new SphereGeometry(8, 50, 50);
  let mater = new MeshStandardMaterial({
    envMap: scene.background,
    color: 0xffffff,
    metalness: 1,
    roughness: 0.5,
  });
  
  let textureLoader = new TextureLoader()
  let mater1 = mater.clone();
  // 金属光泽度贴图
  mater1.metalnessMap = textureLoader.load('/textures/engraved/roughness-map.jpg');
  let mesh1 = new Mesh(sphere1, mater1);
  mesh1.position.x = -10;
  mesh1.rotation.y = 1/3 * Math.PI;
  scene.add(mesh1);

  let mater2 = mater.clone();
  // 粗糙度贴图
  mater2.roughnessMap = textureLoader.load('/textures/engraved/roughness-map.jpg');
  let mesh2 = new Mesh(sphere1, mater2);
  mesh2.position.x = 10;
  mesh2.rotation.y = -1/3 * Math.PI;
  scene.add(mesh2);

  return sphereMesh
}


function addGUI(mesh: MeshStandardMaterial): void {
  const controls = {
    displacementScale: 0,
    displacementBias: 0,
  }
  const gui = new GUI();  
  gui.add(controls, 'displacementScale', -5, 5, 0.01).onChange(val => {
    mesh.displacementScale = val
  });
  gui.add(controls, 'displacementBias', -5, 5, 0.01).onChange(val => {
    mesh.displacementBias = val
  })
}